"""
serializers.py 是
Django REST Framework (DRF) 中的一个模块，用于定义序列化器（Serializer）。
序列化器是将复杂的数据结构（如 Django 模型实例）转换为可用于网络传输或存储的格式（如 JSON）的过程。
通过定义序列化器，您可以控制数据的序列化和反序列化过程，以及指定哪些字段应该包含在序列化输出中。
提供的代码中，UserSerializer 类是一个自定义的序列化器，用于序列化和反序列化 User 模型的数据。
它继承自 serializers.Serializer 类，这是 DRF 中最基本的序列化器类。
"""
# from urllib import request

from django.contrib.auth.hashers import make_password
from rest_framework import serializers
from user.models import User, Role, Clazz
# 导入官方的DynamicFieldsModelSerializer 序列化器
from djangoProject12.serializers import DynamicFieldsModelSerializer


# 使用官方的序列化器，能够自定义传入字段
# class AddressSerializer(DynamicFieldsModelSerializer):
#     """地址模型序列化器，用于地址数据的序列化和反序列化"""
#     # 方式1.处理一的关系属性，username不能进行添加
#     # username = serializers.ReadOnlyField(source="user.username")
#
#     # 方式3. 使用序列化器嵌套，将user的序列化器嵌套到address的序列化器中，user的序列化器中不能有address的序列化器
#     # user = UserSerializer()
#
#     # 方式4. 使用HyperlinkedRelatedField，将user 变成一个超链接，指向user的详情页面
#     # context = {'request': request} 会返回绝对路径
#     # context = {'request': request} 会返回相对路径 ，去掉http://...
#     # user = serializers.HyperlinkedRelatedField(view_name='user:detail', read_only=True, lookup_field='pk')
#
#     # 5.(新)定义一个计算属性、并使用 method_name 来设置函数名称，函数名称必须是 get_ + 字段名
#     address = serializers.SerializerMethodField(method_name='get_address_text')
#
#     def get_address_text(self, obj):
#         """计算属性，用于返回地址的文本信息"""
#         return f"{obj.pro}{obj.city}{obj.country}{obj.detail}"
#
#     class Meta:
#         model = Address
#         fields = "__all__"
#
#         # 方式2.设置关系属性序列化的深度（处理一的关系属性），敏感信息会暴露
#         # depth = 1


class UserSerializer(serializers.ModelSerializer):
    """用户模型序列化器，用于用户数据的序列化和反序列化"""

    # address_list = AddressSerializer(many=True, read_only=True)

    class Meta:
        # 用来关联 模型
        model = User
        # 1.设置 fields(白名单) 序列化器需要序列化的字段
        # 如果希望展示所有字段，直接使用 fields = '__all__'
        # fields = ["id", "username", "email", "tel", "avatar"]
        # fields = '__all__'

        # 2.设置 exclude（黑名单） 序列化器需要排除的字段
        # fields 和 exclude 不能同时使用，是互斥的，必须只存在一个
        exclude = ["groups", "user_permissions"]

        # 3.设置 read_only_fields 只读字段
        read_only_fields = ["date_joined", "id", "last_login"]

        # 4.设置 extra_kwargs 额外的关键字参数
        extra_kwargs = {
            # 将密码设置成只能写，不能读取，防止密码被读取
            "password": {"write_only": True},
            # 将邮箱设置成必填项
            "email": {"required": True},
        }

    def create(self, validated_data):
        """可以重写create方法，来对密码进行加密"""
        # 该方法不能激活用户，需要手动激活
        validated_data["is_active"] = True
        # 返回数据，密码能够进行加密
        return User.objects.create_user(**validated_data)

    def update(self, instance, validated_data):
        """可以重写update方法，来对密码进行加密"""
        for key, value in validated_data.items():
            # 将密码进行加密
            if key == "password":
                # setattr 是 Python 中的一个内置函数，用于设置对象的属性值。
                # setattr(object, name, value)
                # object：要设置属性的对象。
                # name：属性的名称，必须是一个字符串。
                # value：要设置的属性值。
                setattr(instance, key, make_password(value))
            # 将账号进行激活
            elif key == "is_active":
                instance.is_active = True
            else:
                setattr(instance, key, value)

        instance.save()
        return instance

    # # 用户ID，整数类型
    # id = serializers.IntegerField(read_only=True)
    #
    # # 用户名，字符串类型
    # username = serializers.CharField()
    #
    # # 电子邮箱，EmailField会自动验证邮箱格式
    # email = serializers.EmailField()
    #
    # # 电话号码，字符串类型
    # tel = serializers.CharField(required=False)
    #
    # # 性别，字符串类型
    # gender = serializers.CharField(required=False)
    #
    # # 头像文件，FileField用于处理文件上传
    # avatar = serializers.FileField(required=False)
    #
    # # 密码字段，write_only=True表示只在创建/更新时使用，不会在序列化输出中显示
    # # 设置密码只写
    # password = serializers.CharField(write_only=True)
    #
    # is_active = serializers.BooleanField(required=False)
    #
    # # 是否可以访问后台，布尔类型
    # is_staff = serializers.BooleanField(required=False, default=True)
    #
    # # 是否是超级用户，布尔类型
    # is_superuser = serializers.BooleanField(required=False, default=True)
    #
    # # 注册时间，DateTimeField会自动处理日期时间格式
    # date_joined = serializers.DateTimeField(required=False)
    #
    # def create(self, validated_data):
    #     """
    #     实现数据的添加
    #     :param validated_data: 已经校验通过的数据
    #     :return:
    #     """
    #     return User.objects.create_superuser(**validated_data)
    #
    # def update(self, instance, validated_data):
    #     """
    #     实现数据的修改
    #     :param instance: 模型对象
    #     :param validated_data: 已经校验通过的数据
    #     :return:
    #     """
    #     # 更新用户名，如果validated_data中没有提供则保持原值
    #     instance.username = validated_data.get("username", instance.username)
    #     # 更新邮箱，如果validated_data中没有提供则保持原值
    #     instance.email = validated_data.get("email", instance.email)
    #     # 更新电话号码，如果validated_data中没有提供则保持原值
    #     instance.tel = validated_data.get("tel", instance.tel)
    #     # 更新性别，如果validated_data中没有提供则保持原值
    #     instance.gender = validated_data.get("gender", instance.gender)
    #     # 更新头像文件，如果validated_data中没有提供则保持原值
    #     instance.avatar = validated_data.get("avatar", instance.avatar)
    #     # 更新密码，使用set_password方法确保密码被正确哈希存储
    #     instance.set_password(validated_data.get("password", instance.password))
    #     # 更新激活状态，如果validated_data中没有提供则保持原值
    #     instance.is_active = validated_data.get("is_active", instance.is_active)
    #     # 更新是否能访问后台，如果validated_data中没有提供则保持原值
    #     instance.is_staff = validated_data.get("is_staff", instance.is_staff)
    #     # 更新是否是超级用户，如果validated_data中没有提供则保持原值
    #     instance.is_superuser = validated_data.get("is_superuser", instance.is_superuser)
    #     # 更新注册时间，如果validated_data中没有提供则保持原值
    #     instance.date_joined = validated_data.get("date_joined", instance.date_joined)
    #     # 保存数据
    #     instance.save()
    #     # 返回更新后的模型对象
    #     return instance


class AddressModelSerializer(serializers.ModelSerializer):
    """地址模型序列化器，用于地址数据的序列化和反序列化"""

    class Meta:
        # model = Address
        fields = "__all__"
        extra_kwargs = {
            # 设置都不是必填项
            "user": {"required": False},
            "pro": {"required": False},
            "city": {"required": False},
            "country": {"required": False},
            "detail": {"required": False},
        }


class UserFormSerializer(DynamicFieldsModelSerializer):
    class Meta:
        model = User
        exclude = ["groups", "user_permissions"]

    def create(self, validated_data):
        return User.objects.create_user(**validated_data)


class RoleSerializer(DynamicFieldsModelSerializer):
    class Meta:
        model = Role
        fields = '__all__'


class ClazzSerializer(DynamicFieldsModelSerializer):
    class Meta:
        model = Clazz
        fields = '__all__'


class UsersSerializer(DynamicFieldsModelSerializer):
    role = serializers.ReadOnlyField(source='role.name')

    class Meta:
        model = User
        exclude = ["groups", "user_permissions"]
